package org.madmac.faixaIp;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;

import org.madmac.exception.IpNotFoundException;
import org.madmac.ip.Ip;
import org.wakeful.conn.Connection;

public class FaixaIpDao {

	private static FaixaIpDao instance;

	private FaixaIpDao() {
	}

	public static FaixaIpDao getInstance() {
		if (instance == null) {
			instance = new FaixaIpDao();
		}
		return instance;
	}

	public String findNextIp() throws Exception {
		Statement stmt = null;
		ResultSet rs = null;
		String ip = null;
		try {
			java.sql.Connection conn = Connection.getInstance();
			stmt = conn.createStatement();
			rs = stmt.executeQuery(FaixaIpQuery.findNextIp());
			if (rs.next()) {
				ip = rs.getString("next_ip");
			}
		} catch (Exception e) {
			throw new Exception(e);
		} finally {
			if (stmt != null) {
				stmt.close();
			}
			if (rs != null) {
				rs.close();
			}
		}
		return ip;
	}

	public Ip selectMaxIp() throws SQLException, ClassNotFoundException, Exception {

		Ip search_ip = null;
		java.sql.Connection conn = Connection.getInstance();
		Statement stmt = conn.createStatement();
		String sql = "SELECT faixa_fi + 1 AS maxip FROM madmac.faixa_ip WHERE ";
		sql += "id_faixa_ip = (SELECT MAX(id_faixa_ip) FROM madmac.faixa_ip)";

		ResultSet rs = null;
		try {
			rs = stmt.executeQuery(sql);
		} catch (Exception e) {
			return null;
		}

		if (rs.next()) {

			search_ip = new Ip();
			String ip = rs.getString("maxip");
			search_ip.setIp(ip);

		} else {
			throw new IpNotFoundException();
		}
		return search_ip;
	}

	public List<FaixaIp> findFaixaIpLivre() throws Exception {
		
		List<FaixaIp> list = new ArrayList<FaixaIp>();
		Statement stmt = null;
		ResultSet rs = null;
		try {
			java.sql.Connection conn = Connection.getInstance();
			stmt = conn.createStatement();
			rs = stmt.executeQuery(FaixaIpQuery.findFaixaIpLivre());

			while (rs.next()) {
				FaixaIp faixa = new FaixaIp();

				faixa.setIdFaixa(rs.getInt("id_faixa_ip"));
				faixa.setFaixaIni(rs.getString("faixa_in"));
				faixa.setFaixaFim(rs.getString("faixa_fi"));
				faixa.setDescricao(rs.getString("descricao"));
				faixa.setNumIpLivre(rs.getInt("num_ip_livre"));

				list.add(faixa);
			}
		} catch (Exception e) {
			throw new Exception(e);
		} finally {
			if (stmt != null) {
				stmt.close();
			}
			if (rs != null) {
				rs.close();
			}
		}
		return list;
	}

	public FaixaIp findById(Integer idFaixaIp) throws Exception {
		FaixaIp faixaIp = null;
		PreparedStatement pstmt = null;
      ResultSet rs = null;
		try {
			java.sql.Connection conn = Connection.getInstance();
         pstmt = conn.prepareStatement(FaixaIpQuery.retrieve());
			pstmt.setInt(1, idFaixaIp);
			rs = pstmt.executeQuery();
         if (rs.next()) {
            faixaIp = new FaixaIp();
				faixaIp.setIdFaixa(rs.getInt("id_faixa_ip"));
				faixaIp.setFaixaIni(rs.getString("faixa_in"));
				faixaIp.setFaixaFim(rs.getString("faixa_fi"));
				faixaIp.setDescricao(rs.getString("descricao"));
			}
		} catch (Exception e) {
			throw new Exception(e);
      } finally {
         if (pstmt != null) {
            pstmt.close();
         }
         if (rs != null) {
            rs.close();
         }
		}
		return faixaIp;
	}

	public List<FaixaIp> findAll() throws Exception {
		List<FaixaIp> list = new ArrayList<FaixaIp>();
		Statement stmt = null;
		ResultSet rs = null;
		try {
			java.sql.Connection conn = Connection.getInstance();
			stmt = conn.createStatement();
			rs = stmt.executeQuery(FaixaIpQuery.findAll());

			while (rs.next()) {
				FaixaIp faixaIp = new FaixaIp();

				faixaIp.setIdFaixa(rs.getInt("id_faixa_ip"));
				faixaIp.setFaixaIni(rs.getString("faixa_in"));
				faixaIp.setFaixaFim(rs.getString("faixa_fi"));
				faixaIp.setDescricao(rs.getString("descricao"));

				list.add(faixaIp);
			}
		} catch (Exception e) {
			throw new Exception(e);
		} finally {
			if (stmt != null) {
				stmt.close();
			}
			if (rs != null) {
				rs.close();
			}
		}
		return list;
	}

	/**
	 *
	 * @return
	 * @throws SQLException
	 * @throws ClassNotFoundException
	 * @throws Exception
	 * @deprecated Use findFaixaIpLivre(void)
	 */
	public List<FaixaIp> selectAll() throws SQLException, ClassNotFoundException, Exception {

		List<FaixaIp> lista = new ArrayList<FaixaIp>();

		java.sql.Connection conn = Connection.getInstance();
		Statement stmt = conn.createStatement();
		String sql = "SELECT * FROM madmac.faixa_ip ORDER BY faixa_in ";

		ResultSet rs = null;
		try {
			rs = stmt.executeQuery(sql);
		} catch (Exception e) {

			return null;
		}

		while (rs.next()) {

			FaixaIp faixa = new FaixaIp();

			faixa.setIdFaixa(rs.getInt("id_faixa_ip"));
			faixa.setFaixaIni(rs.getString("faixa_in"));
			faixa.setFaixaFim(rs.getString("faixa_fi"));
			faixa.setDescricao(rs.getString("descricao"));

			lista.add(faixa);
		}
		return lista;
	}

	public boolean insertFaixaIp(FaixaIp faixa) throws SQLException, ClassNotFoundException, Exception {

		boolean resultado = false;
		Statement stmt = null;
		try {
			java.sql.Connection conn = Connection.getInstance();
			stmt = conn.createStatement();
			String sql = "INSERT INTO madmac.faixa_ip (faixa_in, faixa_fi, descricao) ";
			sql += "VALUES ('" + faixa.getFaixaIni() + "', ";
			sql += "'" + faixa.getFaixaFim() + "', ";
			sql += "'" + faixa.getDescricao().toLowerCase() + "') ";
			int count = stmt.executeUpdate(sql);
			resultado = false;
			if (count == 1) {
				resultado = true;
			}
		} catch (Exception e) {
			throw new Exception(e);
		} finally {
			if (stmt != null) {
				stmt.close();
			}
		}
		return resultado;
	}

	public Object create(FaixaIp faixaIp) throws Exception {
		PreparedStatement pstmt = null;
		Integer id = null;
		ResultSet rs = null;
		try {
			java.sql.Connection conn = Connection.getInstance();
			pstmt = conn.prepareStatement(FaixaIpQuery.create());
			pstmt.setObject(1, faixaIp.getFaixaIni(), Types.OTHER);
			pstmt.setObject(2, faixaIp.getFaixaFim(), Types.OTHER);
			pstmt.setString(3, faixaIp.getDescricao());
			rs = pstmt.executeQuery();
			if (rs.next()) {
				id = rs.getInt("id_faixa_ip");
			}
		} catch (Exception e) {
			throw new Exception(e);
		} finally {
			if (pstmt != null) {
				pstmt.close();
			}
			if (rs != null) {
				rs.close();
			}
		}
		return id;
	}

	// FIXME: retirar int up_id_faixa.
	public boolean updateDescricao(FaixaIp faixa, int up_id_faixa) throws SQLException, ClassNotFoundException, Exception {

		PreparedStatement pstmt = null;
		boolean resultado = false;
		try {
			java.sql.Connection conn = Connection.getInstance();
			pstmt = conn.prepareStatement(FaixaIpQuery.update());
			pstmt.setString(1, faixa.getDescricao());
			pstmt.setInt(2, up_id_faixa);
			resultado = false;

			int count = pstmt.executeUpdate();

			if (count > 0) {
				resultado = true;
			}
		} catch (Exception e) {
			throw new Exception(e);
		} finally {
			if (pstmt != null) {
				pstmt.close();
			}
		}
		return resultado;
	}

	public int selectMaxFaixaIp() throws SQLException, ClassNotFoundException, Exception {

		int lastFaixa = 0;
		java.sql.Connection conn = Connection.getInstance();
		Statement stmt = conn.createStatement();

		ResultSet rs = null;
		try {
			rs = stmt.executeQuery(FaixaIpQuery.selectLastFaixaIp());
			if (rs.next()) {
				lastFaixa = rs.getInt("last");
			}
		} catch (Exception e) {
			return 0;
		} finally {
			stmt.close();
			if (rs != null) {
				rs.close();
			}
		}
		return lastFaixa;
	}
}
